package com.sw.c.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sw.c.common.Result;
import com.sw.c.common.ResultCodeEnum;
import com.sw.c.config.SystemParams;
import com.sw.c.mapper.RolePermissionMapper;
import com.sw.c.mapper.UserMapper;
import com.sw.c.mapper.UserRoleMapper;
import com.sw.c.mapper.mongodb.UserMongo;
import com.sw.c.pojo.entity.Permission;
import com.sw.c.pojo.entity.RolePermission;
import com.sw.c.pojo.entity.User;
import com.sw.c.pojo.entity.UserMongoDB;
import com.sw.c.pojo.vo.UserVo;
import com.sw.c.service.UserService;
import com.sw.c.utils.JwtTokenUtil;
import com.sw.c.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private RolePermissionMapper permissionMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserMongo userMongo;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private SystemParams systemParams;

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    public List<Permission> getRolePermissionTree(Integer pid, List<Integer> roleId, Integer userId) {

        // 根据角色ID获取权限列表
        //List<Permission> rolePermissionList = permissionMapper.getByRoleIds(roleId);
        // 查询全部菜单
        List<Permission> rolePermissionListAll = permissionMapper.getByRoleIdAll();
        //System.out.println("菜单数据:" + rolePermissionList.toString());
        System.out.println("全部菜单数据:" + rolePermissionListAll.toString());

        // 提取权限ID列表
        //List<Integer> rolePermissionIds = rolePermissionList.stream().map(Permission::getId).collect(Collectors.toList());
        List<Integer> rolePermissionIdsAll = rolePermissionListAll.stream().map(Permission::getId).collect(Collectors.toList());
        //System.out.println("菜单ID数据:" + rolePermissionIds.toString());
        System.out.println("全部菜单ID数据:" + rolePermissionIdsAll.toString());

        List<Permission> myPermissionList = permissionMapper.getByRoleIds(roleId);
        List<Integer> myPermissionIds = myPermissionList.stream().map(Permission::getId).collect(Collectors.toList());
        // 组装树形结构
        List<Permission> treeMenu = rolePermissionListAll.stream()
                .filter(t -> t.getPid() == 0)
                .map((permission) -> {
                    // 判断当前菜单是否有子菜单，若有则递归调用获取子菜单
                    if (myPermissionIds.contains(permission.getId())) {
                        permission.setChecked(true);
                        permission.setChildren(getUserMenuChildren(permission, rolePermissionListAll, myPermissionIds));
                    } else {
                        permission.setChecked(false);
                    }
                    return permission;
                })
                .sorted((permission1, permission2) -> {
                    return (permission1.getSort() == null ? 0 : permission1.getSort()) - (permission2.getSort() == null ? 0 : permission2.getSort());
                })
                .collect(Collectors.toList());

        return treeMenu;
    }



    private List<Permission> getUserMenuChildren(Permission root, List<Permission> all, List<Integer> myPermissionIds) {

        // 查询全部菜单
        List<Permission> childrenList = all.stream()
                .filter(t -> t.getPid().equals(root.getId()))
                .map(item -> {
                    // 判断当前子菜单是否有子菜单，若有则递归调用获取子菜单
                    if (myPermissionIds.contains(item.getId())) {
                        item.setChecked(true);
                        item.setChildren(getUserMenuChildren(item, all, myPermissionIds)); // 传递新的角色菜单 ID 列表
                    } else {
                        item.setChecked(false);
                        item.setChildren(new ArrayList<>());
                    }
                    return item;
                })
                // 菜单排序
                .sorted((permission1, permission2) -> {
                    return (permission1.getSort() == null ? 0 : permission1.getSort()) - (permission2.getSort() == null ? 0 : permission2.getSort());
                })
                .collect(Collectors.toList());

        return childrenList;
    }

    /**
     * 修改角色菜单
     * @param roleId
     * @param permissionIds
     */
    @Override
    @Transactional
    public String updateRolePermission(Integer roleId, List<Integer> permissionIds) {
        try {
            // 首先删除旧的权限菜单
            permissionMapper.deleteByIds(roleId);
            // 批量插入新的权限菜单
            List<RolePermission> rolePermissions = new ArrayList<>();
            for (Integer permissionId : permissionIds) {
                RolePermission rolePermission = new RolePermission();
                rolePermission.setRoleId(roleId);
                rolePermission.setPermissionId(permissionId);
                rolePermissions.add(rolePermission);
            }
            permissionMapper.batchInsert(rolePermissions);

            return "角色菜单更新成功";
        } catch (Exception e) {
            log.error("更新角色菜单失败: " + e.getMessage());
            return "更新角色菜单失败";
        }
    }

    @Override
    public void delById(Integer delRole) {
        permissionMapper.delRole(delRole);
    }

    @Override
    public List<Permission> getTree(Integer userId) {

        //查出用户所有权限id
        List<Integer> roleList = userRoleMapper.getPermissionIds(userId);
        if (CollectionUtils.isEmpty(roleList)) {
            return null;
        }
        //根据用户所有权限id，查询对应菜单
        List<Permission> permissions = permissionMapper.getByUserIdList(roleList);


        List<Permission> tree = new ArrayList<>(); // 最终的树形结构
        Set<Integer> addedIds = new HashSet<>(); // 用于存储已添加的权限节点的 id，避免重复添加

        for (Permission permission : permissions) {
            if (Objects.equals(permission.getPid(), 0)) { // 如果菜单的父节点id为0，说明是根节点
                tree.add(permission); // 将根节点添加到树中
                addedIds.add(permission.getId()); // 将根节点的id添加到 Set 中，表示已添加过
            } else {
                addChild(tree, permission, addedIds); // 如果不是根节点，则调用 addChild 方法添加到树中
            }
        }

        return tree; // 返回构建好的树形结构
    }


    private void addChild(List<Permission> permissions, Permission child, Set<Integer> addedIds) {
        for (Permission permission : permissions) {
            if (Objects.equals(permission.getId(), child.getPid())) { // 找到该子节点的父节点
                if (!addedIds.contains(child.getId())) { // 如果子节点还没有被添加过
                    if (permission.getChildren() == null) {
                        permission.setChildren(new ArrayList<>()); // 如果父节点的子节点列表为空，初始化为空列表
                    }
                    permission.getChildren().add(child); // 将子节点添加到父节点的子节点列表中
                    addedIds.add(child.getId()); // 将子节点的id添加到 Set 中，表示已添加过
                }
                break; // 添加完成后退出循环
            } else if (permission.getChildren() != null) {
                addChild(permission.getChildren(), child, addedIds); // 递归查找父节点
            }
        }
    }



/*    @Override
    public List<Permission> getSubkeyTree(Integer perId) {
        // 获取所有政区数据。假设 permissionMapper.getAll() 方法从数据库中获取所有政区记录。
        List<Permission> allPermissions = permissionMapper.getAll();

        // 初始化一个空列表用于存储树型结构的根节点
        List<Permission> tree = new ArrayList<>();

        // 先构建一个 id 到 Permission 对象的映射，方便快速查找
        // permissionMap 的键是政区的 id，值是对应的 Permission 对象
        Map<Integer, Permission> permissionMap = new HashMap<>();
        for (Permission permission : allPermissions) {
            permissionMap.put(permission.getId(), permission);
        }

        // 遍历所有政区数据，查找所有根节点，即其父节点 ID 为 perId 的菜单
        for (Permission permission : allPermissions) {
            if (permission.getId().equals(perId)) {
                // 如果当前带单的 ID 匹配 perId，则将其作为根节点，并开始构建其树形结构
                tree.add(buildTree(permission, permissionMap));
            }
        }

        // 返回构建好的树型结构
        return tree;
    }

    // 递归构建树型结构
    private Permission buildTree(Permission root, Map<Integer, Permission> permissionMap) {
        // 创建一个列表用于存储当前根节点的子节点
        List<Permission> children = new ArrayList<>();

        // 遍历映射中的所有政区，查找其父节点 ID 匹配当前根节点的 ID 的政区
        for (Map.Entry<Integer, Permission> entry : permissionMap.entrySet()) {
            Permission child = entry.getValue();
            if (child.getPid().equals(root.getId())) {
                // 如果子节点的父节点 ID 匹配当前根节点的 ID，则递归构建子节点的树型结构
                children.add(buildTree(child, permissionMap));
            }
        }
        // 将所有找到的子节点设置到当前根节点的 children 属性中
        root.setChildren(children);

        // 返回构建好的树型结构的根节点
        return root;
    }*/


    @Override
    public List<Permission> getSubkeyTree(Map<String,Object> params) {
        // 获取所有政区数据
        List<Permission> allPermissions = permissionMapper.getAll();

        // 创建一个映射，id到Permission对象的映射
        Map<Integer, Permission> permissionMap = new HashMap<>();
        for (Permission permission : allPermissions) {
            permissionMap.put(permission.getId(), permission);
        }

        // 创建列表用于存储树型结构的根节点
        List<Permission> tree = new ArrayList<>();

        // 定义一个递归方法来构建树型结构
        Function<Permission, Permission> buildTree = new Function<Permission, Permission>() {
            @Override
            public Permission apply(Permission root) {
                // 创建一个列表用于存储子节点
                List<Permission> children = new ArrayList<>();

                // 遍历映射中的所有政区，查找当前根节点的子节点
                for (Map.Entry<Integer, Permission> entry : permissionMap.entrySet()) {
                    Permission child = entry.getValue();
                    if (child.getPid().equals(root.getId())) {
                        // 递归构建子节点的树型结构
                        children.add(apply(child));
                    }
                }

                // 将找到的子节点设置到当前根节点的 children 属性中
                root.setChildren(children);
                return root;
            }
        };

        // 查找所有根节点并构建树型结构
        for (Permission permission : allPermissions) {
            if (permission.getId().equals(params.get("id"))) {
                tree.add(buildTree.apply(permission));
            }
        }

        return tree;
    }

    @Override
    public IPage<User> pagelist(Integer pageNum,Integer pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);

        // 构造条件构造器
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

        // 添加排序条件
        queryWrapper.orderByDesc(User::getCreateTime);

        // 执行查询并获取结果
        IPage<User> resultPage = userMapper.selectPage(page, queryWrapper);
        return resultPage;
    }



    @Override
    public List<UserMongoDB> getAllUser() {
        List<UserMongoDB> all = userMongo.findAll();
        for (UserMongoDB user:all) {
            log.info("user:{}",JSON.toJSONString(user));
        }
        return all;
    }

    @Override
    public Result demo(User user) {
        if (user.getUsername().equals("admin") && user.getPassword().equals("admin")) {

            UserVo vo = new UserVo();
            vo.setId(1);
            vo.setUsername("admin");

            String userToken = JSON.toJSONString(vo);

            String token = jwtTokenUtil.generateToken(userToken);
            vo.setToken(token);

            redisUtils.set(systemParams.getRedisPrefix() + vo.getUsername(), token, systemParams.getRedisTime());
//            redisUtils.set(systemParams.getRedisPrefix() + "domeUser", vo, systemParams.getRedisTime());
            return Result.success(vo);
        } else {
            return Result.error(ResultCodeEnum.ERROR_LOGIN);
        }
    }

}
